﻿#include<iostream>
#include<string>
#include<vector>
#include<typeinfo>
using namespace std;

//继承
class Person
{
public:
	Person()
	{
		++_count;
		cout << "Person()" << endl;
		//cout << _name << endl;
	}
	Person(const char* name, const int age)
		:_name(name)
		, _age(age)
	{
		cout << "Person(const string& name, const int& age)" << endl;
	}

	Person(const Person& p)
		:_name(p._name)
		, _age(p._age)
	{
		cout << "Person(const Person& p)" << endl;
	}

	Person& operator=(const Person& p)
	{
		cout << "Person& operator=(const Person& p)" << endl;
		if (this != &p)
		{
			_name = p._name;
			_age = p._age;
		}
		return *this;
	}

	~Person()
	{
		cout << "~Person()" << endl;
	}

protected:
	string _name = "nullptr";
	int _age = 0;
	int _count = 0;
};


class Student : public Person
{
public:
	Student()
	{
		cout << "Student()" << endl;
		cout << _count << endl;
	}
	Student(const char* name, const int age, const char* id)
		:Person(name, age)
		, _student_id(id)
	{
		cout << "Student(const char* name,const int age,const char* id)" << endl;
	}

	Student(const Student& s)
		:Person(s)
		, _student_id(s._student_id)
	{
		cout << "Student(const Student& s)" << endl;
	}

	Student& operator=(const Student& s)
	{
		cout << "Student& operator=(const Person& s)" << endl;
		if (this != &s)
		{
			Person::operator=(s);
			_student_id = s._student_id;
		}
		return *this;
	}

	~Student()
	{
		cout << "~Student()" << endl;
	}
protected:
	string _student_id = "123456";
};


//#define vector CONTAINER

//利用继承实现栈
template <class T>
class Stack :public vector<T>
{
public:
	void push(const T& x)
	{
		vector<T>::push_back(x);
	}
	void pop()
	{
		vector<T>::pop_back();
	}
	const T& top()
	{
		return vector<T>::back();
	}
	void empty()
	{
		vector<T>::empty();
	}
};

//多态
//抽象类
class Animal
{
public:
	virtual void bark()//虚函数
	{

	}
};
class Dog : public Animal
{
public:
	virtual void bark()
	{
		cout << "汪汪汪、、" << endl;
   }
};

class Cat :public Animal
{
public:
	virtual void bark()
	{
		cout << "(> ^ ω ^ < )喵喵喵" << endl;
	}
};

void letsHear(Animal* a)
{
	a->bark();
}

void letsHear(Animal& a)
{
	a.bark();
}

//下面的程序输出结果是什么？
//考察对多态的理解
class A1
{
public:
	virtual void func(int val = 1)
	{
		std::cout << "A1->" << val << std::endl;
	}
	virtual void test()
	{
		func();
	}
};
//本质是this调用func(),this为父类对象的指针
		//func是被子类重写的虚函数，所以构成多态，传什么执行什么
		//多态虚函数重写本质是父类虚函数声明+子类虚函数定义
		
//	virtual void func(int val = 1)
//{
//	std::cout << "B->" << val << std::endl;
//}


class B1 : public A1
{
public:
	void func(int val = 0) 
	{ 
		std::cout << "B1->" << val << std::endl;
	}
};
void Test1()
{
	B1* p = new B1;
	p->test();
}
class A2 { 
public: 
	void test(float a)
	{ 
		cout << a; 
	} 
};
class B2:public A2
{ 
public: 
	void test(int b) 
{ 
	cout << b;
	}
}; 
void Test2() 
{
	A2* a = new A2;
	B2* b = new B2;
	a = b;
	a->test(1.1); 
} 



class A3
{
public:
	virtual ~A3()
	{
		cout << "~A3()" << endl;
	}
};
class B3 : public A3 {
public:
	~B3()
	{
		cout << "~B3()->delete:" << _p << endl;
		delete _p;
	}
protected:
	int* _p = new int[10];
};


//子类和父类的析构函数本质上都被编译器命名为destructor()
// 只有⼦类Student的析构函数重写了Person的析构函数，下⾯的delete对象调⽤析构函数，才能构
//成多态（与类型无关，只与指向的对象有关）才能保证p1和p2指向的对象正确的调⽤析构函数。
void  Test3()
{
	A3* p1 = new A3;
	A3* p2 = new B3;
	delete p1;
	delete p2;
}

class A4
{
public:
	A4() :m_iVal(0) { test(); }
	virtual void func() { std::cout << m_iVal << " "; }
	void test() { func(); }
public:
	int m_iVal;
};

class B4 : public A4
{
public:
	B4() { test(); }
	virtual void func()
	{
		++m_iVal;
		std::cout << m_iVal << " ";
	}
};

void Test4()
{
	A4* p = new B4;
	p->test();
}


class Base
{
public:
	virtual void Func1()
	{
		cout << "Func1()" << endl;
	}
protected:
	int _b = 1;
	char _ch = 'x';
};
void Test5()
{
	Base b; 
	cout << sizeof(b) << endl;
}


int main()
{
	Test5();
	return 0;
}
